package stack.CatDogQueue;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class CatDogQueue {

    private Stack<PetCount> dogStack;

    private Stack<PetCount> catStack;

    private int count=0;

    public CatDogQueue() {
        this.dogStack = new Stack<>();
        this.catStack = new Stack<>();
    }

    public void add(Pet pet){
        if(pet instanceof Cat){
            this.catStack.push(new PetCount(pet,++count));
        }else{
            this.dogStack.push(new PetCount(pet,++count));
        }
    }

    /**
     * 将队列中所有实例按照进队列的先后顺序依次弹出
     * @return
     */
    public List<Pet> pollAll(){

        List<Pet> result = new ArrayList<>(dogStack.size() + catStack.size());

        while (!this.isEmpty()){

            if(dogStack.isEmpty()){
                addAllStackElementToList(this.catStack,result);
                break;
            }

            if(catStack.isEmpty()){
                addAllStackElementToList(this.dogStack,result);
                break;
            }

            PetCount dogPetCount = dogStack.pop();
            PetCount catPetCount = catStack.pop();

            if(dogPetCount.getCount()> catPetCount.getCount()){
                result.add(dogPetCount.getPet());

                while (!this.dogStack.isEmpty()&&dogStack.peek().getCount()> catPetCount.getCount()){
                    result.add(dogStack.pop().getPet());
                }

                result.add(catPetCount.getPet());
            }else{
                result.add(catPetCount.getPet());

                while (!this.catStack.isEmpty()&&catStack.peek().getCount()> dogPetCount.getCount()){
                    result.add(catStack.pop().getPet());
                }

                result.add(dogPetCount.getPet());
            }

        }

        return result;
    }

    private void addAllStackElementToList(Stack<PetCount> petStack, List<Pet> result) {

        while (!petStack.isEmpty()){
            result.add(petStack.pop().getPet());
        }

    }


    public boolean isEmpty(){
        return this.catStack.isEmpty()&&this.dogStack.isEmpty();
    }
}
